#ifndef QSNAKE_H
#define QSNAKE_H

#include <QLabel>
#include <QThread>
#include <QObject>


//定义snake一些样式
#define BOYD_STYLE "background-color: rgb(138, 226, 5);border-radius: 10px;"
#define HEAD_STYLE "background-color: rgb(234, 7, 5);border-radius: 10px;"
#define TAIL_STYLE "background-color: rgb(23, 27, 45);border-radius: 10px;"
#define FROG_STYLE1 "background-color: rgb(100, 255, 0);border-radius: 10px;"
#define FROG_STYLE2 "background-color: rgb(50, 255, 100);border-radius: 2px;"
#define AREA_STYLE  "background-color: rgba(220, 220, 220,125);"

//定义一些信号码
#define SNAKE_NULL -1
#define SNAKE_OVER 0   //结束
#define IS_WALL 1     //撞墙
#define IS_BODY 2     //撞身体
#define FULL_AREA 3   //满屏幕
#define EATEN 4       //吃掉食物
#define SNAKE_MOVE 5  //移到

//采用label形式显示节点
typedef QLabel showType;

typedef struct
{
    enum nodetype{head,body,tail};
    nodetype type;//节点类型
    showType *disp;//节点显示方式 disp属于显示窗口，不允许在PlaySanke中修改，可以通过信号把指针和需要的参数送回主窗口修改
    QString style;//节点显示样式
    int x;
    int y;
    int step; //节点移动步长或者边长或者半径

}snakeNode,*snakeNodePtr;

//采用链表形式存放节点，可以采用list vector或者自定义容器存放节点
//容器类需要有实现：frist(),last(),at(),size()等模板类容器具有的特性
typedef QList<snakeNodePtr> snakeType;

//定义一个管理蛇属性的对象类
class PlaySnake : public QThread
{
    Q_OBJECT

public:

    enum Direction{Up,Down,Left,Right};

    //构造函数，parent为snake的显示窗口
    PlaySnake(QWidget *parent = nullptr);
    ~PlaySnake(){}

    //设置蛇到活动区域，相对于主窗口parent,边界必须是step到整数倍
    void setRect(int w,int h, int x=0 ,int y=0);
    //设置移动速度值
    void setSpeed(int speed){g_speed = speed;}
    //设置加速标志
    void setSpeedFlag(bool flag){g_speedFlag = flag;}
    //设置移动方向
    void setDirection(Direction indirect = Right);
    //设置移动步长
    void setStep(int instep){step = instep;}
    //设置蛇操作对象
    void setSnake(snakeType *tsnake){snake = tsnake;}
    //设置青蛙操作对象
    void setFrog(snakeNodePtr frog){this->frog = frog;}
    //移动
    void move(int step_x ,int step_y);
    //设置节点样式
    void setStyle(QString style,snakeNode::nodetype nodetype);
    bool eating();
    //判断位置
    bool isBody();
    bool isWall();
    bool isBody(int x ,int y);
    bool isWall(int x ,int y);
    //新建一个青蛙位置
    bool creatFrog(int &x , int &y);

    void stop(){runing = false;}
    void setpause(bool pause){this->pause = pause;}

signals:
    //由主窗口更新显示，更新节点样式或者节点位置
    void updataStyle(showType *lab, QString style);
    void updataNode(showType *lab, QString style,int x,int y ,int step);
    //当青蛙被吃，重新更新
    bool eaten(int x,int y,int step);
    //信号触发码
    int snakeMsg(int code);


protected:
    virtual void run();
private:
    int g_speed;
    bool g_speedFlag;
    bool step_flag;
    bool runing;
    bool pause;
    Direction direct;
    int step;
    snakeType *snake;
    snakeNodePtr frog;
    int area_w;
    int area_h;
    int area_x;
    int area_y;
    QWidget *parent;
};
//博客：booinon
//https://blog.csdn.net/boonion?spm=1011.2415.3001.5343
#endif // QSNAKE_H

